Skip to content

fix(ci): skip already-uploaded wheels on publish rerun#241

Merged
pratyush618 merged 2 commits into
masterfrom
fix/publish-skip-existing
Jun 11, 2026
Merged

fix(ci): skip already-uploaded wheels on publish rerun#241
pratyush618 merged 2 commits into
masterfrom
fix/publish-skip-existing

Conversation

@pratyush618

@pratyush618 pratyush618 commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add skip-existing: true to pypa/gh-action-pypi-publish step
  • Prevents 400 File already exists when rerunning failed publish jobs (e.g. transient Rekor/Sigstore failures that crash after partial upload)

Test plan

  • Verified 0.16.0 wheels already on PyPI from partial first run
  • Next tag push exercises updated workflow

Summary by CodeRabbit

  • Chores
    • More reliable publishing that avoids duplicate uploads when artifacts already exist on PyPI.
    • Pre-publish validation of built packages to catch packaging issues and filename/hash conflicts before release.
    • Conditional publish logic to skip uploading already-published artifacts.
    • Automated post-publication verification with retries to confirm new versions are available on PyPI.

@github-actions github-actions Bot added the ci label Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds pre-publish artifact validation, a PyPI JSON check that compares remote filenames to local dist/ and sets all_uploaded, conditions publishing on that flag with skip-existing: true, and adds a retry loop that verifies the published version is reachable on PyPI.

Changes

PyPI Publish Workflow Update

Layer / File(s) Summary
Validate built artifacts
.github/workflows/publish.yml
Installs twine, attempts to unzip wheels in dist/, and runs twine check --strict against dist/* before attempting to publish.
Check PyPI for existing version
.github/workflows/publish.yml
Fetches PyPI JSON for the tag version, extracts remote filenames and digests, compares them to local dist/ filenames and SHA256 hashes, fails on hash conflicts, and sets all_uploaded output.
Conditional publish with skip-existing
.github/workflows/publish.yml
Runs pypa/gh-action-pypi-publish only when all_uploaded != 'true' and configures skip-existing: true to tolerate already-uploaded artifacts.
Verify version on PyPI (retry loop)
.github/workflows/publish.yml
Polls PyPI JSON up to 5 times (15s sleeps) to confirm the version is visible, failing the job if not found after retries.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰
I checked each wheel and opened the crate,
I asked PyPI kindly, "Is this version late?"
If files exist, skip-upload keeps the pace,
I poll and wait a few short beats to trace,
Then dance — the release appears in its place.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding skip-existing functionality to prevent reupload errors during publish reruns.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/publish-skip-existing

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Note

Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/publish.yml:
- Line 268: The publish workflow currently sets skip-existing: true on the
pypa/gh-action-pypi-publish@release/v1 step which makes twine return success
even if every distribution was skipped; update the workflow to detect and fail
when nothing was uploaded by (a) capturing the action/twine output (look for
"Skipping upload" or "File already exists") and adding a follow-up step that
parses that output to fail the job when all artifacts were skipped, or (b) add a
conditional input to the publish step that disables skip-existing for production
publishes and document the behavior in the workflow comment; reference the
publish step using the action id (pypa/gh-action-pypi-publish@release/v1) and
the skip-existing input to locate where to implement the check and the
documentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e779bd81-61a8-4caf-b590-3076b7c38945

📥 Commits

Reviewing files that changed from the base of the PR and between e177791 and bc63acb.

📒 Files selected for processing (1)
  • .github/workflows/publish.yml

Comment thread .github/workflows/publish.yml
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

✅ Created PR with unit tests: #242

@pratyush618
pratyush618 force-pushed the fix/publish-skip-existing branch from 5d3b4d6 to 5cf954b Compare June 11, 2026 03:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/publish.yml:
- Line 276: The for-loop declares a counter named attempt that is never used,
triggering SC2034; update the loop header in the publish workflow to either
replace the unused variable with an underscore (for attempt in 1 2 3 4 5; do ->
for _ in 1 2 3 4 5; do) or reference attempt in the loop body (e.g., include
attempt in a logging statement) so the variable is no longer unused; adjust the
loop in the same block where the variable attempt is declared.
- Around line 268-271: The comment incorrectly states duplicate tag pushes will
fail; update .github/workflows/publish.yml to either (a) correct the comment to
say a duplicate push can succeed when skip-existing: true, or (preferred) change
the publish flow to detect “nothing new uploaded” by parsing the publish step
output (the step that runs twine / uses pypa/gh-action-pypi-publish) and fail
the job if every artifact was skipped; implement this by capturing the
action/command output from the publish step (e.g., step id "publish" or the job
step that sets skip-existing) and checking for messages like "Skipping upload" /
"Already exists" / "No files were uploaded" and then add a conditional failure
when all artifacts are skipped, or alternatively disable skip-existing for
production publishes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 60185699-28fe-4329-be4a-9a0991d3e6c9

📥 Commits

Reviewing files that changed from the base of the PR and between bc63acb and 5d3b4d6.

📒 Files selected for processing (1)
  • .github/workflows/publish.yml

Comment thread .github/workflows/publish.yml Outdated
Comment thread .github/workflows/publish.yml Outdated
@pratyush618
pratyush618 force-pushed the fix/publish-skip-existing branch 3 times, most recently from 22cc990 to a86d259 Compare June 11, 2026 03:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/publish.yml:
- Line 298: Replace the mutable ref uses: pypa/gh-action-pypi-publish@release/v1
with an immutable commit SHA from the pypa/gh-action-pypi-publish repo: locate
the uses line (uses: pypa/gh-action-pypi-publish@release/v1) in the workflow and
change it to use the full commit SHA for the release/v1 branch (e.g.,
pypa/gh-action-pypi-publish@<full_commit_sha>), ensuring you copy the exact
commit SHA from the upstream repo and commit that updated reference so the
action is pinned immutably.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 85c85c01-c3fb-444c-82b7-fcea2ea57411

📥 Commits

Reviewing files that changed from the base of the PR and between 5d3b4d6 and 22cc990.

📒 Files selected for processing (1)
  • .github/workflows/publish.yml

Comment thread .github/workflows/publish.yml Outdated
@pratyush618
pratyush618 force-pushed the fix/publish-skip-existing branch 2 times, most recently from c1c8351 to 92b6d10 Compare June 11, 2026 03:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/publish.yml:
- Around line 286-287: The PyPI probe calls must use explicit timeouts: pass a
timeout to urllib.request.urlopen(req) (e.g., urlopen(req, timeout=30)) so the
Python probe fails fast, and update the shell "curl" invocation (the curl call
around lines 327-329) to include connection and overall timeouts (e.g.,
--connect-timeout 10 and --max-time 30) or run curl via subprocess.run with a
timeout argument; modify the calls referencing urlopen(req) and the curl
invocation accordingly so neither call can hang indefinitely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c3756866-e74c-4c1b-8cd8-773efe0a25a9

📥 Commits

Reviewing files that changed from the base of the PR and between 22cc990 and a86d259.

📒 Files selected for processing (1)
  • .github/workflows/publish.yml

Comment thread .github/workflows/publish.yml Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant